<template>
  <div class="content-container">
    <div class="base-table-container">
      <div ref="refChatItems" class="chat-items" @scroll="checkScrollTop">
        <div v-if="msgLoading" class="no-msg">正在加载历史消息~~</div>
        <div v-else-if="!msgList.length" class="no-msg">暂无更多消息~~</div>
        <TextMsgView
          v-for="item in msgList"
          :row="item"
          :key="item.id"
          @menu="hanldeContextMenu(item)"
          @quote="hanldeQuote(item)"
        />
      </div>
      <div class="input-container">
        <div class="message-input-toolbar-list">
          <customEmojiPicker @select="onSelectEmoji" />
          <ImageUpload @sendImage="handleSendImage" />
          <FileUpload @sendFile="handleSendFile" />
        </div>
        <MsgInput
          ref="refTextInput"
          v-model="textInput"
          @enter="handleSend"
          @sendImage="handleSendImage"
          @sendFile="handleSendFile"
        />
        <QuoteView v-model="quoteMsg" type="1" />
        <el-button
          class="send-btn"
          type="primary"
          :loading="sendLoading"
          @click="handleSend"
          >{{ sendLoading ? '等待回复' : $t('push.send') }}</el-button
        >
      </div>
    </div>
  </div>
</template>

<script setup>
import TextMsgView from '@/views/message/chatMessage/component/TextMsgView.vue'
import customEmojiPicker from '@/views/message/chatMessage/component/EmojiPicker.vue'
import ImageUpload from '@/views/message/chatMessage/component/ImageUpload.vue'
import FileUpload from '@/views/message/chatMessage/component/FileUpload.vue'
import MsgInput from '@/views/message/chatMessage/component/MsgInput.vue'
import QuoteView from '@/views/message/chatMessage/component/QuoteView.vue'

const userStore = useUserStore()
const { userInfo, eventSource } = storeToRefs(userStore)
// 聊天参数
const refChatItems = ref(null)
const msgLoading = ref(false)
const msgList = ref([])
const pageNum = ref(1)
const refTextInput = ref(null)
const textInput = ref('')
const quoteMsg = ref('')
const sendLoading = ref(false)
const timer = ref(null)
// 取消请求参数
const controller = ref(null)

watch(
  () => msgList.value.length,
  (nv, ov) => {
    if (nv !== ov) {
      nextTick(() => {
        scrollToBottom()
      })
    }
  },
  {
    deep: true
  }
)

onMounted(() => {
  controller.value = new AbortController()
  getChatMsg()
  eventSource.value.on('chat-ai', chatMsgDeal)
  refChatItems.value.addE
})

onBeforeUnmount(() => {
  // 如果存在未完成的请求，则取消它
  if (controller.value) {
    controller.value.abort()
    console.log('controller.value-取消未完成的请求!')
  }
  eventSource.value.off('chat-ai', chatMsgDeal)
})

const chatMsgDeal = event => {
  // console.log('on chat-ai', event)
  nextTick(() => {
    const data = JSON.parse(event.data).data
    console.log('chat-ai-data', data)
    if (data.toId !== '2' && data.toId !== userInfo.value.userId) return
    if (data.fromId === '2') {
      clearTimeout(timer.value)
      sendLoading.value = false
    }
    const foundItem = msgList.value.find(item => {
      return (
        String(item.id) === String(data.id) ||
        (data.tagId && String(item.tagId) === String(data.tagId))
      )
    })
    data.sending = false
    if (foundItem) {
      // 如果找到相同id或tagId的项，合并数据
      Object.assign(foundItem, data)
    } else {
      msgList.value.push(data)
    }
  })
}

const getChatMsg = () => {
  msgLoading.value = true
  msgList.value = []
  // if (pageNum.value === 1) msgList.value = [] // 仅第一页清空
  g_api.sysMsg
    .apiMsgList(
      {
        userId: userInfo.value.userId,
        toId: '2',
        source: 'ai',
        pageNum: pageNum.value,
        pageSize: 300
      },
      {},
      {
        signal: controller.value.signal
      }
    )
    .then(({ code, data }) => {
      if (code === '200' && data) {
        // const ids = msgList.value.map(item => item.id)
        // const dataList = data.items.filter(item => !ids.includes(item.id))
        // console.log('dataList', dataList)
        // // 现有的消息列表包含当前请求的数据，需要再查询数据
        // if (pageNum.value > 1 && data.items.length && !dataList.length) {
        //   pageNum.value++
        //   getChatMsg()
        // }
        // if (pageNum.value === 1) scrollToBottom()
        // msgList.value.unshift(...dataList)
        msgList.value = data.items
      }
    })
    .finally(() => {
      msgLoading.value = false
    })
}

const querySearchAsync = g_.debounce(() => {
  console.log('获取更多数据')
  // pageNum.value++
  // getChatMsg()
}, 300)

const checkScrollTop = () => {
  if (refChatItems.value) {
    if (refChatItems.value.scrollTop < 10) {
      // 获取更多数据
      querySearchAsync()
    }
  }
}

const sendChatMsg = msgBody => {
  console.log('sendChatMsg', msgBody)
  sendLoading.value = true
  // 如果消息已断开，就重新链接一次
  // if (eventSource.value.eventSource.readyState === 2) {
  //   userStore.startSSEClient()
  //   eventSource.value.on('chat-ai', chatMsgDeal)
  // }
  clearTimeout(timer.value)
  timer.value = setTimeout(() => {
    sendLoading.value = false
  }, 30000)
  msgList.value.push({
    ...msgBody,
    sending: true
  })
  g_api.sysMsg
    .apiMsgCreate(msgBody)
    .then(({ code, data }) => {
      // if (code === '200' && data) {
      // }
    })
    .finally(() => {
      textInput.value = ''
      quoteMsg.value = ''
    })
}

const scrollToBottom = () => {
  setTimeout(() => {
    if (!refChatItems.value) return
    refChatItems.value.scrollTop =
      refChatItems.value.scrollHeight - refChatItems.value.offsetHeight
  })
}

const hanldeContextMenu = row => {
  console.log('hanldeContextMenu', row)
  msgList.value = msgList.value.map(item => {
    if (item.id === row.id) {
      item.contextMenuVisible = true
    } else {
      item.contextMenuVisible = false
    }
    return item
  })
}

const hanldeQuote = row => {
  console.log('hanldeQuote', row)
  quoteMsg.value = row
}

const onSelectEmoji = emoji => {
  const msgLength = emoji.native.length
  const inputEl = refTextInput.value?.refNwMsgInput
  if (inputEl) {
    const startPos = inputEl.selectionStart
    textInput.value = `${textInput.value.slice(0, startPos)}${
      emoji.native
    }${textInput.value.slice(startPos)}`
    refTextInput.value.focus()
    nextTick(() => {
      // 此处是根据元素的长度，来设置光标位置
      inputEl.setSelectionRange(startPos + msgLength, startPos + msgLength)
    })
  }
}

const handleSendMsg = () => {
  return {
    fromId: userInfo.value.userId,
    toId: '2',
    fromInfo: {
      id: userInfo.value.userId,
      name: userInfo.value.nickName,
      avatar: userInfo.value.avatar || '',
      type: 'ai'
    },
    // message: '{"content":"你好，我想订车"}',
    referenceMsg: quoteMsg.value || undefined,
    // atUser: {
    //   id: '0ff09f3a80324ffabc76c90bc1b5af0e',
    //   name: '张三',
    //   avatar: 'https://file.neoway.com/d/private/images/flower.jpg'
    // },
    source: 'ai',
    tagId: Date.now(),
    createTime: g_dayjs().format('YYYY-MM-DD HH:mm:ss')
    // contextMenuVisible: false // 右键菜单是否可见
  }
}

const uploadFile = (files, type) => {
  const file = files[0]
  // console.log(file)
  sendLoading.value = true
  const formData = new FormData()
  formData.append('file', file)

  g_api.travelAgency
    .apiFileUpload(formData, {
      'Content-Type': 'multipart/form-data' // 关键！
    })
    .then(({ code, data }) => {
      if (code === '200' && data) {
        sendChatMsg({
          ...handleSendMsg(),
          type,
          message: JSON.stringify({
            url: data.url,
            name: file.name,
            size: file.size
          })
        })
      }
    })
    .finally(() => {
      sendLoading.value = false
    })
}

const handleSendImage = files => {
  uploadFile(files, 'photo')
}

const handleSendFile = files => {
  uploadFile(files, 'file')
}

const handleSend = () => {
  console.log('handleSend', textInput.value)
  if (!sendLoading.value && textInput.value.trim()) {
    sendChatMsg({
      ...handleSendMsg(),
      type: 'text',
      message: JSON.stringify({
        content: textInput.value
      })
    })
    textInput.value = ''
    quoteMsg.value = ''
  }
}
</script>

<style lang="scss" scoped>
.content-container {
  flex-direction: row;
}
.base-table-container {
  display: flex;
  flex-direction: column;
}
.chat-items {
  flex: 1;
  overflow-y: auto;
  padding-bottom: 10px;
  .no-msg {
    text-align: center;
    font-size: 12px;
    color: #666;
  }
}
.message-input-toolbar-list {
  display: flex;
  flex-direction: row;
  align-items: center;
  :deep() {
    .toolbar-item-container {
      position: relative;
    }
    .toolbar-item-container-icon {
      cursor: pointer;
      padding: 8px;
      display: flex;
    }
    .common-icon {
      width: 20px;
      height: 20px;
    }
  }
}
.input-container {
  position: relative;
  background-color: #fff;
  box-shadow: 0 0 0 1px #dcdfe6;
  border-radius: 4px;
  .send-btn {
    position: absolute;
    bottom: 5px;
    right: 5px;
    padding: 5px 15px;
  }
}
</style>
